package com.kwdb.sdk.serialization;

import com.kwdb.sdk.data.DataPoint;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Map;
import java.util.HashMap;

/**
 * Telegraf Line Protocol解析器 - 序列化层实现
 * 
 * 支持格式：measurement,tag1=value1,tag2=value2 field1=value1,field2=value2 timestamp
 */
public class LineProtocolParser {
    
    private static final Pattern LINE_PATTERN = Pattern.compile(
        "^([^\\s,]+)(?:,([^\\s]+))?\\s+(.+?)(?:\\s+(\\d+))?$"
    );
    
    private static final Pattern TAG_PATTERN = Pattern.compile("([^=,]+)=([^=,]+)");
    private static final Pattern FIELD_PATTERN = Pattern.compile("([^=,]+)=([^=,]+)");
    
    /**
     * 解析Line Protocol格式字符串
     * @param lineProtocol Line Protocol字符串
     * @return DataPoint对象
     */
    public DataPoint parse(String lineProtocol) {
        if (lineProtocol == null || lineProtocol.trim().isEmpty()) {
            throw new IllegalArgumentException("Line Protocol字符串不能为空");
        }
        
        String line = lineProtocol.trim();
        Matcher matcher = LINE_PATTERN.matcher(line);
        
        if (!matcher.matches()) {
            throw new IllegalArgumentException("无效的Line Protocol格式: " + line);
        }
        
        String measurement = unescapeString(matcher.group(1));
        String tagsStr = matcher.group(2);
        String fieldsStr = matcher.group(3);
        String timestampStr = matcher.group(4);
        
        DataPoint dataPoint = new DataPoint(measurement);
        
        // 解析标签
        if (tagsStr != null && !tagsStr.isEmpty()) {
            Map<String, String> tags = parseTags(tagsStr);
            for (Map.Entry<String, String> tag : tags.entrySet()) {
                dataPoint.addTag(tag.getKey(), tag.getValue());
            }
        }
        
        // 解析字段
        if (fieldsStr != null && !fieldsStr.isEmpty()) {
            Map<String, Object> fields = parseFields(fieldsStr);
            for (Map.Entry<String, Object> field : fields.entrySet()) {
                Object value = field.getValue();
                if (value instanceof String) {
                    dataPoint.addField(field.getKey(), (String) value);
                } else if (value instanceof Integer) {
                    dataPoint.addField(field.getKey(), ((Integer) value).intValue());
                } else if (value instanceof Long) {
                    dataPoint.addField(field.getKey(), ((Long) value).longValue());
                } else if (value instanceof Double) {
                    dataPoint.addField(field.getKey(), ((Double) value).doubleValue());
                } else if (value instanceof Boolean) {
                    dataPoint.addField(field.getKey(), ((Boolean) value).booleanValue());
                } else {
                    dataPoint.addField(field.getKey(), value.toString());
                }
            }
        }
        
        // 解析时间戳
        if (timestampStr != null && !timestampStr.isEmpty()) {
            try {
                long timestamp = Long.parseLong(timestampStr);
                dataPoint.setTimestamp(timestamp);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("无效的时间戳格式: " + timestampStr);
            }
        }
        
        return dataPoint;
    }
    
    /**
     * 将DataPoint转换为Line Protocol格式
     * @param dataPoint 数据点
     * @return Line Protocol字符串
     */
    public String toLineProtocol(DataPoint dataPoint) {
        return dataPoint.toLineProtocol();
    }
    
    /**
     * 解析标签字符串
     * @param tagsStr 标签字符串
     * @return 标签映射
     */
    private Map<String, String> parseTags(String tagsStr) {
        Map<String, String> tags = new HashMap<>();
        Matcher matcher = TAG_PATTERN.matcher(tagsStr);
        
        while (matcher.find()) {
            String key = unescapeString(matcher.group(1));
            String value = unescapeString(matcher.group(2));
            tags.put(key, value);
        }
        
        return tags;
    }
    
    /**
     * 解析字段字符串
     * @param fieldsStr 字段字符串
     * @return 字段映射
     */
    private Map<String, Object> parseFields(String fieldsStr) {
        Map<String, Object> fields = new HashMap<>();
        Matcher matcher = FIELD_PATTERN.matcher(fieldsStr);
        
        while (matcher.find()) {
            String key = unescapeString(matcher.group(1));
            String value = unescapeString(matcher.group(2));
            Object typedValue = parseFieldValue(value);
            fields.put(key, typedValue);
        }
        
        return fields;
    }
    
    /**
     * 解析字段值并推断类型
     * @param value 字段值字符串
     * @return 类型化的值
     */
    private Object parseFieldValue(String value) {
        if (value == null || value.isEmpty()) {
            return "";
        }
        
        // 字符串类型（带引号）
        if (value.startsWith("\"") && value.endsWith("\"")) {
            return value.substring(1, value.length() - 1);
        }
        
        // 布尔类型
        if ("true".equals(value) || "false".equals(value)) {
            return Boolean.parseBoolean(value);
        }
        
        // 数字类型
        try {
            // 尝试解析为整数
            if (value.contains(".")) {
                return Double.parseDouble(value);
            } else {
                return Long.parseLong(value);
            }
        } catch (NumberFormatException e) {
            // 解析失败，作为字符串处理
            return value;
        }
    }
    
    /**
     * 反转义字符串
     * @param str 原始字符串
     * @return 反转义后的字符串
     */
    private String unescapeString(String str) {
        if (str == null) {
            return "";
        }
        
        return str.replaceAll("\\\\([,= ])", "$1");
    }
    
    /**
     * 转义字符串
     * @param str 原始字符串
     * @return 转义后的字符串
     */
    private String escapeString(String str) {
        if (str == null) {
            return "";
        }
        
        return str.replaceAll("([,= ])", "\\\\$1");
    }
}
